#-*- coding:UTF-8 -*-


import cStringIO
import re
import functools

import model_util as model_util
import session    as session

from .util import get_argument, get_arguments

from ..logger import logger
from ..config import PLATMGT_HOME, get_property
from ..orm.models import *
from ..orm.db_util import get_objects, count_object, get_object_by_id, \
    save_object, delete_object, get_resources, get_actors
from ..ldap import user_existed
from ..security.auth import check_userpass, get_login_user_info
from .props import (URL_PREFIX, APP_PREFIX, LOCAL_HTML_BASE, HTML_URL_BASE, 
                    HOME_URL, LOGIN_URL, NOT_FOUND_URL)


def sidebar_menu_lighter(menu_levels=''):
    def wrapper(func):
        @functools.wraps(func)
        def wrapped_f(*args, **kwargs):
            result = func(*args, **kwargs)
            if result is None:
                result = dict()
            ml = menu_levels.strip('/')
            items = ml.split('/')
            for item in items:
                if result.has_key(item):
                    logger.debug(
                        'error in sidebar_menu_lighter key(%s) exists'%item)
                result[item] = True
            return result
        return wrapped_f
    return wrapper


@sidebar_menu_lighter('m0')
def get_home(hanlder):
    user_count   = count_object(User)
    group_count  = count_object(Group)
    system_count = count_object(System)
    host_count   = count_object(Host)
    render_dict = dict({})
    #render_dict['m0'] = True
    render_dict['user_count'] = user_count
    render_dict['group_count'] = group_count
    render_dict['system_count'] = system_count
    render_dict['host_count'] = host_count
    return render_dict


def get_test(handler):
    '''
    host_list = get_objects(Host, attr_list=['datacenter', 'creator'])
    render_dict = dict({'m2':True, 'm23':True})
    render_dict['host_list'] = host_list
    return render_dict
    '''
    return 12 / 0


def get_404(handler):
    return dict({})

def get_error(handler):
    ex = handler.get_session().pop_attribute('exception')
    st = handler.get_session().pop_attribute('stacktrace')
    return{'exception':ex, 'stacktrace':st}


@sidebar_menu_lighter('m1/m11')
def get_ug_users(handler):
    user_list = get_objects(User)
    return {'user_list':user_list}


@sidebar_menu_lighter('m1/m12')
def get_ug_groups(handler):
    group_list = get_objects(Group)
    return {'group_list':group_list}


@sidebar_menu_lighter('m2/m21')
def get_res_datacenters(handler):
    datacenter_list = get_objects(DataCenter)
    return {'datacenter_list':datacenter_list}


@sidebar_menu_lighter('m2/m22')
def get_res_systems(handler):
    system_list = get_objects(System, attr_list=['creator'])
    return {'system_list':system_list}


@sidebar_menu_lighter('m2/m23')
def get_res_hosts(handler):
    host_list = get_objects(Host, attr_list=['datacenter', 'creator'])
    return {'host_list':host_list}


@sidebar_menu_lighter('m1/m11')
def get_ug_adduser(handler):
    return {'group_list':get_objects(Group)}


@sidebar_menu_lighter('m1/m12')
def get_ug_addgroup(handler):
    return {'user_list':get_objects(User)}


@sidebar_menu_lighter('m2/m21')
def get_res_adddatacenter(handler):
    render_dict = {}
    #render_dict[''] = 
    return render_dict


@sidebar_menu_lighter('m2/m22')
def get_res_addsystem(handler):
    return {'host_list':get_objects(Host)}


@sidebar_menu_lighter('m2/m23')
def get_res_addhost(handler):
    return {'datacenter_list':get_objects(DataCenter)}


def post_saveobject(handler):
    render_dict = {'m0':True}
    act_type = handler.get_argument('act_type', '')
    if act_type:
        if hasattr(model_util, act_type):
            the_func = getattr(model_util, act_type)
            result_dict = the_func(handler)
            if result_dict['status']:
                render_dict['title'] = 'Success'
                render_dict['content'] = 'Object saved.'
            else:
                render_dict['title'] = 'Failure'
                render_dict['content'] = result_dict['cause']
        else:
            render_dict['title'] = 'Error'
            render_dict['content'] = 'No function to handler.'
    else:
        render_dict['title'] = 'Error'
        render_dict['content'] = 'Action type not identified.'
    '''
    print '-'*40
    print_request_arguments(handler) 
    #for i in dir(handler):
        #print i
        #print 'type = %s, value = %s'%(getattr(handler, i), i)
    print '-'*50
    '''
    return render_dict


@sidebar_menu_lighter('m1/m12')
def get_ug_groupmembers(handler):
    grp_id = handler.get_argument('id', '')
    group = get_object_by_id(Group, grp_id, attr_list=['groupusers.user'])
    if group:
        return {'group':group}


@sidebar_menu_lighter('m1/m12')
def get_ug_updategroup(handler):
    grp_id = handler.get_argument('id', '')
    group = get_object_by_id(Group, grp_id, attr_list=['groupusers.user'])
    all_users = get_objects(User)
    group_members = []
    for gu in group.groupusers:
        group_members.append(gu.user)
    if group:
        return {'group':group, 'group_members':group_members, \
            'all_users':all_users}


@sidebar_menu_lighter('m1/m12')
def get_ug_deletegroup(handler):
    grp_id = handler.get_argument('id', '')


@sidebar_menu_lighter('m2/m21')
def get_res_dchosts(handler):
    dc_id = handler.get_argument('id', '')
    dc = get_object_by_id(DataCenter, dc_id, attr_list=['hosts.creator'])
    if dc:
        return {'datacenter':dc}


@sidebar_menu_lighter('m2/m21')
def get_res_updatedc(handler):
    dc_id = handler.get_argument('id', '')
    dc = get_object_by_id(DataCenter, dc_id, attr_list=['hosts'])
    host_list = get_objects(Host, datacenter_id=None)
    if dc:
        return {'datacenter':dc, 'host_list':host_list}


@sidebar_menu_lighter('m2/m22')
def get_res_syshosts(handler):
    sys_id = handler.get_argument('id', '')
    sys_obj = get_object_by_id(System, sys_id, \
        attr_list=['systemhosts.host.creator', 'systemhosts.host.datacenter'])
    #host_list = get_objects(Host, attr_list=['creator', 'datacenter'], system_id=None)
    if sys_obj:
        #return dict({'m2':True, 'm22':True, 'system':sys_obj, 'host_list':host_list})
        return {'system':sys_obj}


@sidebar_menu_lighter('m2/m22')
def get_res_updatesystem(handler):
    sys_id = handler.get_argument('id', '')
    sys_obj = get_object_by_id(System, sys_id, attr_list=['systemhosts.host'])
    if sys_obj:
        host_list = get_objects(Host) # there may be duplicated host
        return {'system':sys_obj, 'host_list':host_list}


@sidebar_menu_lighter('m2/m22')
def get_res_deletesystem(handler):
    pass


@sidebar_menu_lighter('m2/m23')
def get_res_updatehost(handler):
    host_id = handler.get_argument('id', '')
    host = get_object_by_id(Host, host_id, attr_list=['datacenter'])
    if host:
        dc_list = get_objects(DataCenter)
        return {'host':host, 'dc_list':dc_list}


@sidebar_menu_lighter('m2/m23')
def get_res_osusers(handler):
    host_id = handler.get_argument('id', '')
    host = get_object_by_id(Host, host_id, attr_list=['auths'])
    if host:
        return {'host':host}


@sidebar_menu_lighter('m2/m23')
def get_res_addosuser(handler):
    host_id = handler.get_argument('id', '')
    host = get_object_by_id(Host, host_id)
    if host:
        return {'host':host}


@sidebar_menu_lighter('m2/m23')
def get_res_updateosuser(handler):
    host_id = handler.get_argument('host_id', '')
    auth_id = handler.get_argument('auth_id', '')
    host = get_object_by_id(Host, host_id)
    auth = get_object_by_id(Auth, auth_id)
    if host:
        return {'host':host, 'auth':auth}


@sidebar_menu_lighter('m3/m31')
def get_perm_resource(handler):
    system_list = get_objects(System, attr_list=['creator'])
    host_list = get_objects(Host, attr_list=['creator'])
    return {'system_list':system_list, 'host_list':host_list}


@sidebar_menu_lighter('m3/m32')
def get_perm_usergroup(handler):
    group_list = get_objects(Group)
    user_list = get_objects(User)
    return {'user_list':user_list, 'group_list':group_list}


@sidebar_menu_lighter('m3/m31')
def get_perm_permsystem(handler):
    sys_id = handler.get_argument('id', '')
    sys_obj = get_object_by_id(System, sys_id)
    all_group_list = get_objects(Group)
    all_user_list  = get_objects(User)
    group_list = get_actors(System, sys_id, Group)
    user_list  = get_actors(System, sys_id, User)
    print 'sys_id =',sys_id
    print 'group_list =',group_list
    print 'user_list =',user_list
    print 'all_group_list =',all_group_list
    print 'all_user_list =',all_user_list
    other_group_list = [i for i in all_group_list if i not in group_list]
    other_user_list  = [i for i in all_user_list  if i not in user_list ]
    return {'system':sys_obj, 'group_list':group_list, 'user_list':user_list, \
        'other_group_list':other_group_list, 'other_user_list':other_user_list}


@sidebar_menu_lighter('m3/m31')
def get_perm_permhost(handler):
    host_id = handler.get_argument('id', '')
    host = get_object_by_id(Host, host_id)
    all_group_list = get_objects(Group)
    all_user_list  = get_objects(User)
    group_list = get_actors(Host, host_id, Group)
    user_list  = get_actors(Host, host_id, User)
    other_group_list = [i for i in all_group_list if i not in group_list]
    other_user_list  = [i for i in all_user_list  if i not in user_list ]
    return {'host':host, 'group_list':group_list, 'user_list':user_list, \
        'other_group_list':other_group_list, 'other_user_list':other_user_list}


@sidebar_menu_lighter('m3/m32')
def get_perm_permgroup(handler):
    group_id = handler.get_argument('id', '')
    group = get_object_by_id(Group, group_id)
    all_system_list = get_objects(System)
    all_host_list   = get_objects(Host)
    system_list = get_resources(Group, group_id, System)
    host_list   = get_resources(Group, group_id, Host)
    other_system_list = [i for i in all_system_list if i not in system_list]
    other_host_list   = [i for i in all_host_list   if i not in host_list  ]
    return {'group':group, 'system_list':system_list, 'host_list':host_list, \
        'other_system_list':other_system_list, 'other_host_list':other_host_list}


@sidebar_menu_lighter('m3/m32')
def get_perm_permuser(handler):
    user_id = handler.get_argument('id', '')
    user = get_object_by_id(User, user_id)
    all_system_list = get_objects(System)
    all_host_list   = get_objects(Host)
    system_list = get_resources(User, user_id, System)
    host_list   = get_resources(User, user_id, Host)
    other_system_list = [i for i in all_system_list if i not in system_list]
    other_host_list   = [i for i in all_host_list   if i not in host_list  ]
    return {'user':user, 'system_list':system_list, 'host_list':host_list, \
        'other_system_list':other_system_list, 'other_host_list':other_host_list}


@sidebar_menu_lighter('m3/m33')
def get_perm_permlist(handler):
    perm_list = get_objects(PermissionMapping)
    map_list = []
    for perm in perm_list:
        actor, res = None, None
        if perm.actor_type == User.__name__:
            actor = get_object_by_id(User, perm.actor_id)
        elif perm.actor_type == Group.__name__:
            actor = get_object_by_id(Group, perm.actor_id)
        else:
            logger.debug(
                'get_perm_permlist actor(%s, %s) not found'%(perm.actor_type, perm.actor_id))
        if perm.res_type == System.__name__:
            res = get_object_by_id(System, perm.res_id)
        elif perm.res_type == Host.__name__:
            res = get_object_by_id(Host, perm.res_id)
        else:
            logger.debug(
                'get_perm_permlist res(%s, %s) not found'%(perm.res_type, perm.res_id))
        if actor and res:
            map_list.append({'id':perm.id, 'actor_type':perm.actor_type, 
                'actor':actor, 'res_type':perm.res_type, 'res':res})
    return {'map_list':map_list}


@sidebar_menu_lighter('m4/m41')
def get_util_fileupload(handler):
    pass


@sidebar_menu_lighter('m4/m42')
def get_util_filedownload(handler):
    pass



def get_login(handler):
    next_url = get_argument(handler, 'next')
    login_failure = session.get_session(handler).pop_attribute('login_failure')
    if login_failure:
        return {'next_url':next_url, 'login_failure':'Login failed and please check password.'}
    else:
        return {'next_url':next_url}


def get_logout(handler):
    session.remove_session(handler)
    #handler.redirect(LOGIN_URL)
    return {'_redirect':LOGIN_URL}

def post_login(handler):
    username, password, next_url = get_argument(handler, 'username', 'password', 'next_url')
    r = check_userpass(username, password)
    if r:
        logger.debug('authentication failed: '+r)
        #login_html_path = os.path.join(LOCAL_HTML_BASE, 'login.html')
        #render_dict = {'HTML_URL_BASE':HTML_URL_BASE, 'error':'error information'}
        #handler.render(login_html_path, **render_dict)
        session.get_session(handler).set_attribute('login_failure', r)
        return {'_redirect':LOGIN_URL}
    else:
        user_id, user_name = get_login_user_info(username)
        handler.get_session().set_user(user_id, user_name)
        if next_url:
            #handler.redirect(next_url)
            return {'_redirect':next_url}
        else:
            #handler.redirect(HOME_URL)
            return {'_redirect':HOME_URL}
    return

##############################################################################################################################



def print_request_arguments(handler):
    '''
    act_type
    host: host_ip host_otherips host_hostname host_servertype host_ostype host_datacenter host_enabled
    system: system_name system_description system_systemtype system_members system_enabled
    datacenter: datacenter_name datacenter_bandwidth datacenter_phone datacenter_address
    user: user_name user_fullname user_groups
    group: group_name group_description group_members
    '''
    print('act type = %s'%handler.get_argument('act_type', 'no type'))
    print('')
    print('host_ip         = %s'%handler.get_argument('host_ip', ''))
    print('host_otherips   = %s'%handler.get_argument('host_otherips', ''))
    print('host_hostname   = %s'%handler.get_argument('host_hostname', ''))
    print('host_servertype = %s'%handler.get_argument('host_servertype', ''))
    print('host_ostype     = %s'%handler.get_argument('host_ostype', ''))
    print('host_datacenter = %s'%handler.get_argument('host_datacenter', ''))
    print('host_enabled    = %s'%handler.get_argument('host_enabled', ''))
    print('')
    print('system_name        = %s'%handler.get_argument('system_name', ''))
    print('system_description = %s'%handler.get_argument('system_description', ''))
    print('system_systemtype  = %s'%handler.get_argument('system_systemtype', ''))
    print('system_members     = %s'%handler.get_argument('system_members', ''))
    print('system_enabled     = %s'%handler.get_argument('system_enabled', ''))
    print('')
    print('datacenter_name      = %s'%handler.get_argument('datacenter_name', ''))
    print('datacenter_bandwidth = %s'%handler.get_argument('datacenter_bandwidth', ''))
    print('datacenter_phone     = %s'%handler.get_argument('datacenter_phone', ''))
    print('datacenter_address   = %s'%handler.get_argument('datacenter_address', ''))
    print('')
    print('user_name     = %s'%handler.get_argument('user_name', ''))
    print('user_fullname = %s'%handler.get_argument('user_fullname', ''))
    print('user_groups   = %s'%handler.get_arguments('user_groups'))
    print('')
    print('group_name        = %s'%handler.get_argument('group_name', ''))
    print('group_name        = %s'%handler.get_arguments('group_name'))
    print('group_description = %s'%handler.get_argument('group_description', ''))
    print('group_members     = %s'%handler.get_arguments('group_members'))
    